package com.loyal.camerax.utils

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import android.util.Log
import android.view.OrientationEventListener
import android.view.Surface
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.preference.PreferenceManager
import com.loyal.camerax.R
import com.loyal.camerax.ui.CameraActivity
import com.loyal.camerax.utils.PreferenceHelper.get

/**切换屏幕横竖屏*/
object ActivityHelper {

    /**
     * 屏幕方向
     */
    fun Activity.screenOrientation() {
        //未指定
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val orientationValue = sharedPreferences.get(getString(R.string.orientation_key))
        Log.e(TAG, "orientationValue: $orientationValue")
        val orientation = orientationValue?.toInt() ?: ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        Log.e(TAG, "orientation: $orientation")

        requestedOrientation = orientation
    }

    /**
     * 旋转方向
     */
    fun Activity.surfaceRotation(): Int {
        var rotation = Surface.ROTATION_0
        when (requestedOrientation) {
            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT -> rotation = Surface.ROTATION_0
            ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT -> rotation = Surface.ROTATION_0
            ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT -> rotation = Surface.ROTATION_0
            ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT -> rotation = Surface.ROTATION_180

            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE -> rotation = Surface.ROTATION_90
            ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE -> rotation = Surface.ROTATION_90
            ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE -> rotation = Surface.ROTATION_90
            ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE -> rotation = Surface.ROTATION_270

            ActivityInfo.SCREEN_ORIENTATION_BEHIND -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_FULL_USER -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_LOCKED -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_NOSENSOR -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_SENSOR -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED -> {
            }

            ActivityInfo.SCREEN_ORIENTATION_USER -> {
            }
        }

        return rotation
    }

    /**
     * 使用findViewById时，要将此方法放在setContentView()之后，如：
     * setContentView(binding.root)
     * orientationChanged(requestedOrientation)
     *
     * 使用binding时，要将此方法放在setContentView()之前，如：
     * orientationChanged(requestedOrientation)
     * setContentView(binding.root)
     */
    fun CameraActivity.orientationChanged(): OrientationEventListener? {
        val orientation = requestedOrientation

        if (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE == orientation) {
            Log.e(TAG, "横屏配置: ")
            fixedLandscape()
        } else if (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT == orientation) {
            Log.e(TAG, "竖屏配置: ")
            fixedPortrait()
        } else if (ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED == orientation) {
            Log.e(TAG, "自动配置: ")
            val mOrientationListener = object : OrientationEventListener(this) {
                override fun onOrientationChanged(orientation: Int) {
                    if (-1 == orientation) return
                    when (orientation) {
                        in 0 until 45, in 315 until 360 -> {//竖屏
                            updateViewRotation(0f, Surface.ROTATION_0)
                        }

                        in 45 until 135 -> {//反向横屏
                            updateViewRotation(270f, Surface.ROTATION_270)
                        }

                        in 135 until 225 -> {//反向竖屏
                            updateViewRotation(180f, Surface.ROTATION_180)
                        }

                        in 225 until 315 -> {//横屏
                            updateViewRotation(90f, Surface.ROTATION_90)
                        }
                    }
                }
            }

            if (mOrientationListener.canDetectOrientation()) {
                Log.e(TAG, "orientationChanged: ENABLE")
                mOrientationListener.enable()
            } else {
                Log.e(TAG, "orientationChanged: DISABLE")
                mOrientationListener.disable()
            }

            return mOrientationListener
        }
        return null
    }

    /**竖屏设置*/
    private fun Activity.fixedPortrait() {
        Log.e(TAG, "fixedPortrait: 竖屏生效")
        /*CONFIG*/
        val configPanel: View? = findViewById(R.id.settingsPanel)
        configPanel?.apply {
            val panelLayoutParams = this.layoutParams as? ConstraintLayout.LayoutParams?
            panelLayoutParams?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
            panelLayoutParams?.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
            panelLayoutParams?.startToStart = ConstraintLayout.LayoutParams.UNSET
            panelLayoutParams?.endToEnd = ConstraintLayout.LayoutParams.UNSET
            panelLayoutParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
            panelLayoutParams?.startToEnd = ConstraintLayout.LayoutParams.UNSET
            panelLayoutParams?.endToStart = ConstraintLayout.LayoutParams.UNSET
            this.layoutParams = panelLayoutParams

            //闪光灯
            val flashView: View? = findViewById(R.id.flash_switch)
            flashView?.let {
                val layoutParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                layoutParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.topToTop = ConstraintLayout.LayoutParams.UNSET
                it.layoutParams = layoutParams
            }
            //设置按钮
            val settingView: View? = findViewById(R.id.camera_setting)
            settingView?.let {
                val layoutParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                layoutParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                it.layoutParams = layoutParams
            }
        }

        /*CAMERA*/
        val cameraBinding: View? = findViewById(R.id.cameraPanel)
        cameraBinding?.apply {
            val panelLayoutParams = this.layoutParams as? ConstraintLayout.LayoutParams?
            panelLayoutParams?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
            panelLayoutParams?.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
            panelLayoutParams?.endToEnd = ConstraintLayout.LayoutParams.UNSET
            panelLayoutParams?.startToStart = ConstraintLayout.LayoutParams.UNSET
            panelLayoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
            this.layoutParams = panelLayoutParams

            //切换
            val cameraSwitch: View? = findViewById(R.id.camera_switch)
            cameraSwitch?.let {
                val switchParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                switchParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                switchParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                switchParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID

                switchParams?.endToStart = ConstraintLayout.LayoutParams.UNSET
                switchParams?.startToEnd = R.id.camera_capture
                switchParams?.horizontalChainStyle = ConstraintLayout.LayoutParams.CHAIN_PACKED
                switchParams?.verticalChainStyle = ConstraintLayout.LayoutParams.UNSET
                it.layoutParams = switchParams
            }
            //相册
            val cameraGallery: View? = findViewById(R.id.camera_gallery)
            cameraGallery?.let {
                val galleryParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                galleryParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.endToStart = R.id.camera_capture

                galleryParams?.startToEnd = ConstraintLayout.LayoutParams.UNSET
                galleryParams?.endToEnd = ConstraintLayout.LayoutParams.UNSET
                it.layoutParams = galleryParams
            }
        }
    }

    /**横屏设置*/
    private fun Activity.fixedLandscape() {
        Log.e(TAG, "fixedLandscape: 横屏生效")
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val gravityValue = sharedPreferences.get(getString(R.string.gravity_key))

        /*CONFIG*/
        val configPanel: View? = findViewById(R.id.settingsPanel)
        configPanel?.apply {
            val panelLayoutParams = this.layoutParams as? ConstraintLayout.LayoutParams?
            panelLayoutParams?.width = 0
            panelLayoutParams?.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
            panelLayoutParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
            if (getString(R.string.gravity_value_left) == gravityValue) {
                panelLayoutParams?.startToEnd = R.id.cameraPanel
                panelLayoutParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
            } else {
                panelLayoutParams?.endToStart = R.id.cameraPanel
                panelLayoutParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
            }
            this.layoutParams = panelLayoutParams

            //闪光灯
            val flashView: View? = findViewById(R.id.flash_switch)
            flashView?.let {
                val layoutParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                layoutParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.topToTop = ConstraintLayout.LayoutParams.UNSET
                it.layoutParams = layoutParams
            }
            //设置按钮
            val settingView: View? = findViewById(R.id.camera_setting)
            settingView?.let {
                val layoutParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                layoutParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                it.layoutParams = layoutParams
            }
        }

        /*CAMERA*/
        val cameraBinding: View? = findViewById(R.id.cameraPanel)
        cameraBinding?.apply {
            val panelLayoutParams = this.layoutParams as? ConstraintLayout.LayoutParams?
            panelLayoutParams?.width = ConstraintLayout.LayoutParams.WRAP_CONTENT
            panelLayoutParams?.height = ConstraintLayout.LayoutParams.MATCH_PARENT
            if (getString(R.string.gravity_value_left) == gravityValue) {
                panelLayoutParams?.endToEnd = ConstraintLayout.LayoutParams.UNSET
                panelLayoutParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
            } else {
                panelLayoutParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
                panelLayoutParams?.startToStart = ConstraintLayout.LayoutParams.UNSET
            }
            panelLayoutParams?.bottomToBottom = ConstraintLayout.LayoutParams.UNSET
            this.layoutParams = panelLayoutParams

            //切换
            val cameraSwitch: View? = findViewById(R.id.camera_switch)
            cameraSwitch?.let {
                val switchParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                switchParams?.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                switchParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
                switchParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
                switchParams?.bottomToBottom = ConstraintLayout.LayoutParams.UNSET

                switchParams?.endToStart = ConstraintLayout.LayoutParams.UNSET
                switchParams?.startToEnd = ConstraintLayout.LayoutParams.UNSET
                switchParams?.bottomToTop = R.id.camera_capture
                switchParams?.horizontalChainStyle = ConstraintLayout.LayoutParams.UNSET
                switchParams?.verticalChainStyle = ConstraintLayout.LayoutParams.CHAIN_PACKED
                it.layoutParams = switchParams
            }

            //相册
            val cameraGallery: View? = findViewById(R.id.camera_gallery)
            cameraGallery?.let {
                val galleryParams = it.layoutParams as? ConstraintLayout.LayoutParams?
                galleryParams?.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
                galleryParams?.topToTop = ConstraintLayout.LayoutParams.UNSET

                galleryParams?.topToBottom = R.id.camera_capture
                galleryParams?.startToEnd = ConstraintLayout.LayoutParams.UNSET
                galleryParams?.endToStart = ConstraintLayout.LayoutParams.UNSET
                it.layoutParams = galleryParams
            }
        }
    }

    fun Context.hasPermissions(permissions: Array<String>): Boolean {
        val refuse = permissions.filter {
            ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
        }
        return refuse.isEmpty()
    }

    fun Activity.showRefuseDialog(settingsLauncher: ActivityResultLauncher<Intent>?) {
        val alertBuilder = AlertDialog.Builder(this)
        alertBuilder.setMessage("请授予相机权限")
            .setPositiveButton("去授权") { dialog, _ ->
                dialog?.dismiss()
                try {
                    val intent = Intent(Settings.ACTION_SETTINGS)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    intent.data = Uri.fromParts("package", packageName, null)
                    settingsLauncher?.launch(intent)
                } catch (e: Exception) {
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    intent.data = Uri.fromParts("package", packageName, null)
                    settingsLauncher?.launch(intent)
                }
            }.setNeutralButton("下次再说") { dialog, _ ->
                dialog?.dismiss()
                finish()
            }
            .setCancelable(false)
            .show()
    }

    fun Activity.hideSystemUI() {
        WindowCompat.setDecorFitsSystemWindows(window, false)
        WindowInsetsControllerCompat(window, window.decorView).let { controller ->
            controller.hide(WindowInsetsCompat.Type.systemBars())
            controller.systemBarsBehavior =
                WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        }
    }
}
